<?php

function explodec($string, $delimitador, $posicao){
	$countletras = strlen($string);
	$countposicao = 0;
	$countvetorposicao = 0;
	$vetor[0] = "";
	$vetor[1] = "";
	for($i=0; $i<$countletras; $i++){
		if($string[$i] == $delimitador){
			$countposicao++;
			if($countposicao == $posicao){
				$countvetorposicao++;
			}else{
				$vetor[$countvetorposicao] .= $string[$i];
			}
		}else{
			$vetor[$countvetorposicao] .= $string[$i];
		}
	}

	return $vetor;
}

function ExplodeOperador($string, $operador){
	$contarmais = substr_count($string, $operador);
	for($i=1; $i<=$contarmais; $i++){
		$e = explodec($string, $operador, $i);
		if(substr_count($e[0], "(") == substr_count($e[0], ")") && substr_count($e[1], "(") == substr_count($e[1], ")")){
			$e[2] = $operador;
			return $e;
		}
	}
}

function ContarOperadorForadeParentesis($string, $operador){
	$contarmais = substr_count($string, $operador);
	$contaroperador = 0;
	for($i=1; $i<=$contarmais; $i++){
		$e = explodec($string, $operador, $i);
		if(substr_count($e[0], "(") == substr_count($e[0], ")") && substr_count($e[1], "(") == substr_count($e[1], ")")){
			$contaroperador++;
		}
	}
	return $contaroperador;
}

/*function parsingrecursivo($string){
	if(ContarOperadorForadeParentesis($string, "+")){
		$e = explodeoperador($string, "+");
	}else if(ContarOperadorForadeParentesis($string, "-")){
		$e = explodeoperador($string, "-");
	}else if(ContarOperadorForadeParentesis($string, "*")){
		$e = explodeoperador($string, "*");
	}else if(ContarOperadorForadeParentesis($string, "/")){
		$e = explodeoperador($string, "/");
	}else if(ContarOperadorForadeParentesis($string, "^")){
		$e = explodeoperador($string, "^");
	}

	print_r($e);
	if(ContarOperadorForadeParentesis($e[0], "+") || ContarOperadorForadeParentesis($e[0], "-") || ContarOperadorForadeParentesis($e[0], "*") || ContarOperadorForadeParentesis($e[0], "/")){
		parsingrecursivo($e[0]);
	}else if(substr_count($e[0], "(")){
		parsingrecursivo(substr($e[0], 1, -1));
	}
	if(ContarOperadorForadeParentesis($e[1], "+") || ContarOperadorForadeParentesis($e[1], "-") || ContarOperadorForadeParentesis($e[1], "*") || ContarOperadorForadeParentesis($e[1], "/")){
		parsingrecursivo($e[1]);	
	}else if(substr_count($e[1], "(")){
		parsingrecursivo(substr($e[1], 1, -1));
	}
}*/

function checkmathfunctionsinsolve($string){

 	global $var_matrix;

	$parenpos = strpos($string, "(");

	foreach($var_matrix as $key => $value) {
    	if($string == $key)
    		return $value;
	}
	
	if(substr($string, 0, $parenpos) == "asinh")
	{
		return asinh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "sinh")
	{
		return sinh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "asin")
	{
		return asin(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "sin")
	{
		return sin(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acosh")
	{
		return acosh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "cosh")
	{
		return cosh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acos")
	{
		return acos(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "cos")
	{
		return cos(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "atanh")
	{
		return atanh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "tanh")
	{
		return tanh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "atan")
	{
		return atan(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "tan")
	{
		return tan(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "asech")
	{
		return acosh(1 / mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "sech")
	{
		return 1 / cosh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "asec")
	{
		return acos(1 / mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "sec")
	{
		return 1 / cos(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acsch")
	{
		return asinh(1 / mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "csch")
	{
		return 1 / sinh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acsc")
	{
		return asin(1 / mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "csc")
	{
		return 1 / sin(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acoth")
	{
		return atanh(1 / mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "coth")
	{
		return 1 / tanh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acot")
	{
		return atan(1 / mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "cot")
	{
		return 1 / tan(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "sqrt")
	{
		return sqrt(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "exp")
	{
		return exp(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "abs")
	{
		return abs(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "log")
	{
		return log(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, 3) == "log")
	{
		return log(mathsolve(substr($string, $parenpos+1, -1)), substr($string, 3, $parenpos-3));
	}
	else if(substr($string, 0, 1) == "(" && substr($string, -1) == ")"){
		return mathsolve(substr($string, 1, -1));
	}
	else if(!is_numeric($string)){
		if($parenpos === false)
			throw new Exception('Mathematical variable '.$string.' has no value defined.');
		else
			throw new Exception('Mathematical function '.substr($string, 0, $parenpos).' does not exist.');
	}else{
		return $string;
	}
}

function checkmathfunctionsinautomaticdiff($string){

 	global $var_matrix, $var_todiff;

	$parenpos = strpos($string, "(");

	foreach($var_matrix as $key => $value) {
    	if($string == $key && $var_todiff == $key){
    		return 1;
    	}
    	else if($string == $key){
    		return 0;
    	}
	}
	
	if(substr($string, 0, $parenpos) == "asinh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / sqrt(pow(mathsolve(substr($string, $parenpos+1, -1)), 2) + 1);
	}
	else if(substr($string, 0, $parenpos) == "sinh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * cosh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "asin")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / sqrt(1 - pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "sin")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * cos(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acosh")
	{
		return - automaticdiff(substr($string, $parenpos+1, -1)) / sqrt(pow(mathsolve(substr($string, $parenpos+1, -1)), 2) - 1);
	}
	else if(substr($string, 0, $parenpos) == "cosh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * sinh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acos")
	{
		return - automaticdiff(substr($string, $parenpos+1, -1)) / sqrt(1 - pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "cos")
	{
		return - automaticdiff(substr($string, $parenpos+1, -1)) * sin(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "atanh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / (1 - pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "tanh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / pow(cosh(mathsolve(substr($string, $parenpos+1, -1))), 2);
	}
	else if(substr($string, 0, $parenpos) == "atan")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / (1 + pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "tan")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * 1 / pow(mathsolve(substr($string, $parenpos+1, -1)), 2);
	}
	else if(substr($string, 0, $parenpos) == "asech")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / ((mathsolve(substr($string, $parenpos+1, -1))) * sqrt((1 - mathsolve(substr($string, $parenpos+1, -1)))/(1 + mathsolve(substr($string, $parenpos+1, -1)))) *(1 + mathsolve(substr($string, $parenpos+1, -1))));
	}
	else if(substr($string, 0, $parenpos) == "sech")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * tan(mathsolve(substr($string, $parenpos+1, -1))) * 1 / cos(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "asec")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (abs(automaticdiff(substr($string, $parenpos+1, -1))) * sqrt(pow(automaticdiff(substr($string, $parenpos+1, -1)), 2) - 1));
	}
	else if(substr($string, 0, $parenpos) == "sec")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (- tanh(mathsolve(substr($string, $parenpos+1, -1)))) * 1 / cosh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acsch")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / (sqrt(1 + (1 / pow(mathsolve(substr($string, $parenpos+1, -1)), 2))) * pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "csch")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (-1 / (sinh(automaticdiff(substr($string, $parenpos+1, -1))) * tanh(automaticdiff(substr($string, $parenpos+1, -1)))));
	}
	else if(substr($string, 0, $parenpos) == "acsc")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / (abs(mathsolve(substr($string, $parenpos+1, -1))) * sqrt(pow(mathsolve(substr($string, $parenpos+1, -1)), 2) - 1));
	}
	else if(substr($string, 0, $parenpos) == "csc")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (-1 / (sin(automaticdiff(substr($string, $parenpos+1, -1))) * tan(automaticdiff(substr($string, $parenpos+1, -1)))));
	}
	else if(substr($string, 0, $parenpos) == "acoth")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / (1 - pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "coth")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (-1 / (pow(sinh(mathsolve(substr($string, $parenpos+1, -1))), 2)));
	}
	else if(substr($string, 0, $parenpos) == "acot")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / (1 + pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "cot")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (-1 / (pow(sin(mathsolve(substr($string, $parenpos+1, -1))), 2)));
	}
	else if(substr($string, 0, $parenpos) == "sqrt")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / (2 * sqrt(mathsolve(substr($string, $parenpos+1, -1))));
	}
	else if(substr($string, 0, $parenpos) == "exp")
	{
		return exp(mathsolve(substr($string, $parenpos+1, -1))) * automaticdiff(substr($string, $parenpos+1, -1));
	}
	else if(substr($string, 0, $parenpos) == "abs")
	{
		return abs(automaticdiff(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "log")
	{
		return 1 / mathsolve(substr($string, $parenpos+1, -1)) * automaticdiff(substr($string, $parenpos+1, -1));
	}
	else if(substr($string, 0, 3) == "log")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / mathsolve(substr($string, $parenpos+1, -1)) * log(substr($string, 3, $parenpos-3), M_E);
	}
	else if(substr($string, 0, 1) == "(" && substr($string, -1) == ")"){
		return automaticdiff(substr($string, 1, -1));
	}
	else if(!is_numeric($string)){
		if($parenpos === false)
			throw new Exception('Mathematical variable '.$string.' has no value defined.');
		else
			throw new Exception('Mathematical function '.substr($string, 0, $parenpos).' does not exist.');
	}else{
		return 0;
	}
}

function symbolicadder($param1, $param2)
{

	if($param1 == "0" && $param2 == "0")
	{
		return 0;
	}
	else if($param1 == "0")
	{
		return $param2;
	}
	else if($param2 == "0")
	{
		return $param1;
	}
	else if(is_numeric($param1) && is_numeric($param2))
	{
		return $param1 + $param2;
	}
	else
	{
		return $param1."+".$param2;
	}
}

function symbolicsubtractor($param1, $param2)
{

	if(!is_numeric($param2) && (ContarOperadorForadeParentesis($param2, "+") || ContarOperadorForadeParentesis($param2, "-"))) $param2 = "(".$param2.")";

	if($param1 == "0" && $param2 == "0")
	{
		return 0;
	}
	else if(is_numeric($param1) && is_numeric($param2))
	{
		return $param1 - $param2;
	}
	else if($param1 == "0")
	{
		return "-".$param2;
	}
	else if($param2 == "0")
	{
		return $param1;
	}
	else
	{
		return $param1."-".$param2;
	}
}

function symbolicmultiplier($param1, $param2)
{

	if(!is_numeric($param1) && (ContarOperadorForadeParentesis($param1, "+") || ContarOperadorForadeParentesis($param1, "-"))) $param1 = "(".$param1.")";
	if(!is_numeric($param2) && (ContarOperadorForadeParentesis($param2, "+") || ContarOperadorForadeParentesis($param2, "-"))) $param2 = "(".$param2.")";

	if($param1 == "0" || $param2 == "0")
	{
		return 0;
	}
	else if($param1 == "1")
	{
		return $param2;
	}
	else if($param2 == "1")
	{
		return $param1;
	}
	else if(is_numeric($param1) && is_numeric($param2))
	{
		return $param1 * $param2;
	}
	else
	{
		return $param1."*".$param2;
	}
}

function symbolicdivisor($param1, $param2)
{

	if(!is_numeric($param1) && (ContarOperadorForadeParentesis($param1, "+") || ContarOperadorForadeParentesis($param1, "-"))) $param1 = "(".$param1.")";
	if(!is_numeric($param2) && (ContarOperadorForadeParentesis($param2, "+") || ContarOperadorForadeParentesis($param2, "-"))) $param2 = "(".$param2.")";

	if($param2 == "0")
	{
		throw new Exception('Division by zero.');
	}
	else if($param1 == "0")
	{
		return 0;
	}
	else if($param2 == "1")
	{
		return $param1;
	}
	else if(is_numeric($param1) && is_numeric($param2))
	{
		return $param1 / $param2;
	}
	else
	{
		return $param1."/".$param2;
	}
}

function symbolicpower($param1, $param2)
{

	if(!is_numeric($param1) && (ContarOperadorForadeParentesis($param1, "+") || ContarOperadorForadeParentesis($param1, "-") || ContarOperadorForadeParentesis($param1, "*") || ContarOperadorForadeParentesis($param1, "/"))) $param1 = "(".$param1.")";
	if(!is_numeric($param2) && (ContarOperadorForadeParentesis($param2, "+") || ContarOperadorForadeParentesis($param2, "-") || ContarOperadorForadeParentesis($param1, "*") || ContarOperadorForadeParentesis($param1, "/"))) $param2 = "(".$param2.")";

	if($param2 == "0")
	{
		return 1;
	}
	else if($param2 == "1")
	{
		return $param1;
	}
	else if($param1 == "1")
	{
		return 1;
	}
	else if($param1 == "0")
	{
		return 0;
	}
	else if(is_numeric($param1) && is_numeric($param2))
	{
		return pow($param1, $param2);
	}
	else
	{
		return $param1."^".$param2;
	}
}

function checkmathfunctionsinsymbolicdiff($string){

 	global $var_matrix, $var_todiff;

	$parenpos = strpos($string, "(");

	foreach($var_matrix as $key => $value) {
    	if($string == $key && $var_todiff == $key){
    		return 1;
    	}
    	else if($string == $key){
    		return 0;
    	}
	}
	
	if(substr($string, 0, $parenpos) == "asinh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / sqrt(pow(mathsolve(substr($string, $parenpos+1, -1)), 2) + 1);
	}
	else if(substr($string, 0, $parenpos) == "sinh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * cosh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "asin")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / sqrt(1 - pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "sin")
	{
		return symbolicmultiplier(symbolicdiff(substr($string, $parenpos+1, -1)), "cos(".substr($string, $parenpos+1, -1).")");
	}
	else if(substr($string, 0, $parenpos) == "acosh")
	{
		return - automaticdiff(substr($string, $parenpos+1, -1)) / sqrt(pow(mathsolve(substr($string, $parenpos+1, -1)), 2) - 1);
	}
	else if(substr($string, 0, $parenpos) == "cosh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * sinh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acos")
	{
		return - automaticdiff(substr($string, $parenpos+1, -1)) / sqrt(1 - pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "cos")
	{
		return symbolicsubtractor(0, symbolicmultiplier(automaticdiff(substr($string, $parenpos+1, -1)), "sin(".substr($string, $parenpos+1, -1).")"));
	}
	else if(substr($string, 0, $parenpos) == "atanh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / (1 - pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "tanh")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / pow(cosh(mathsolve(substr($string, $parenpos+1, -1))), 2);
	}
	else if(substr($string, 0, $parenpos) == "atan")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / (1 + pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "tan")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * 1 / pow(mathsolve(substr($string, $parenpos+1, -1)), 2);
	}
	else if(substr($string, 0, $parenpos) == "asech")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / ((mathsolve(substr($string, $parenpos+1, -1))) * sqrt((1 - mathsolve(substr($string, $parenpos+1, -1)))/(1 + mathsolve(substr($string, $parenpos+1, -1)))) *(1 + mathsolve(substr($string, $parenpos+1, -1))));
	}
	else if(substr($string, 0, $parenpos) == "sech")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * tan(mathsolve(substr($string, $parenpos+1, -1))) * 1 / cos(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "asec")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (abs(automaticdiff(substr($string, $parenpos+1, -1))) * sqrt(pow(automaticdiff(substr($string, $parenpos+1, -1)), 2) - 1));
	}
	else if(substr($string, 0, $parenpos) == "sec")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (- tanh(mathsolve(substr($string, $parenpos+1, -1)))) * 1 / cosh(mathsolve(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "acsch")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / (sqrt(1 + (1 / pow(mathsolve(substr($string, $parenpos+1, -1)), 2))) * pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "csch")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (-1 / (sinh(automaticdiff(substr($string, $parenpos+1, -1))) * tanh(automaticdiff(substr($string, $parenpos+1, -1)))));
	}
	else if(substr($string, 0, $parenpos) == "acsc")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / (abs(mathsolve(substr($string, $parenpos+1, -1))) * sqrt(pow(mathsolve(substr($string, $parenpos+1, -1)), 2) - 1));
	}
	else if(substr($string, 0, $parenpos) == "csc")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (-1 / (sin(automaticdiff(substr($string, $parenpos+1, -1))) * tan(automaticdiff(substr($string, $parenpos+1, -1)))));
	}
	else if(substr($string, 0, $parenpos) == "acoth")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / (1 - pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "coth")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (-1 / (pow(sinh(mathsolve(substr($string, $parenpos+1, -1))), 2)));
	}
	else if(substr($string, 0, $parenpos) == "acot")
	{
		return - (automaticdiff(substr($string, $parenpos+1, -1))) / (1 + pow(mathsolve(substr($string, $parenpos+1, -1)), 2));
	}
	else if(substr($string, 0, $parenpos) == "cot")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) * (-1 / (pow(sin(mathsolve(substr($string, $parenpos+1, -1))), 2)));
	}
	else if(substr($string, 0, $parenpos) == "sqrt")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / (2 * sqrt(mathsolve(substr($string, $parenpos+1, -1))));
	}
	else if(substr($string, 0, $parenpos) == "exp")
	{
		return exp(mathsolve(substr($string, $parenpos+1, -1))) * automaticdiff(substr($string, $parenpos+1, -1));
	}
	else if(substr($string, 0, $parenpos) == "abs")
	{
		return abs(automaticdiff(substr($string, $parenpos+1, -1)));
	}
	else if(substr($string, 0, $parenpos) == "log")
	{
		return 1 / mathsolve(substr($string, $parenpos+1, -1)) * automaticdiff(substr($string, $parenpos+1, -1));
	}
	else if(substr($string, 0, 3) == "log")
	{
		return automaticdiff(substr($string, $parenpos+1, -1)) / mathsolve(substr($string, $parenpos+1, -1)) * log(substr($string, 3, $parenpos-3), M_E);
	}
	else if(substr($string, 0, 1) == "(" && substr($string, -1) == ")"){
		return automaticdiff(substr($string, 1, -1));
	}
	else if(!is_numeric($string)){
		if($parenpos === false)
			throw new Exception('Mathematical variable '.$string.' has no value defined.');
		else
			throw new Exception('Mathematical function '.substr($string, 0, $parenpos).' does not exist.');
	}else{
		return 0;
	}
}

function mathsolve($string){

 	global $var_matrix;

	// Exclui todos os espaços
	$string = str_replace(' ', '', $string);

	if(ContarOperadorForadeParentesis($string, "+")){
		$e = explodeoperador($string, "+");
	}else if(ContarOperadorForadeParentesis($string, "-")){
		$e = explodeoperador($string, "-");
	}else if(ContarOperadorForadeParentesis($string, "*")){
		$e = explodeoperador($string, "*");
	}else if(ContarOperadorForadeParentesis($string, "/")){
		$e = explodeoperador($string, "/");
	}else if(ContarOperadorForadeParentesis($string, "^")){
		$e = explodeoperador($string, "^");
	// Checa todas as funções matemáticas, caso seja uma inexistente retorna uma exceção, caso nenhuma delas, retorna a própria string
	}else{
		return checkmathfunctionsinsolve($string);
	}

	print_r($e);

	// Caso para números negativos
	if($e[0] == "") $e[0] = "0";

	if($e[2] == "+") return mathsolve($e[0]) + mathsolve($e[1]);
	else if($e[2] == "-") return mathsolve($e[0]) - mathsolve($e[1]);
	else if($e[2] == "*") return mathsolve($e[0]) * mathsolve($e[1]);
	else if($e[2] == "/") return mathsolve($e[0]) / mathsolve($e[1]);
	else if($e[2] == "^") return pow(mathsolve($e[0]), mathsolve($e[1]));
}

function automaticdiff($string){

 	global $var_matrix;

	//Exclui todos os espaços
	$string = str_replace(' ', '', $string);

	if(ContarOperadorForadeParentesis($string, "+")){
		$e = explodeoperador($string, "+");
	}else if(ContarOperadorForadeParentesis($string, "-")){
		$e = explodeoperador($string, "-");
	}else if(ContarOperadorForadeParentesis($string, "*")){
		$e = explodeoperador($string, "*");
	}else if(ContarOperadorForadeParentesis($string, "/")){
		$e = explodeoperador($string, "/");
	}else if(ContarOperadorForadeParentesis($string, "^")){
		$e = explodeoperador($string, "^");
	// Checa todas as funções matemáticas, caso seja uma inexistente retorna uma exceção, caso nenhuma delas, retorna a própria string
	}else{
		return checkmathfunctionsinautomaticdiff($string);
	}

	print_r($e);

	// Caso para números negativos
	if($e[0] == "") $e[0] = "0";

	if($e[2] == "+") return automaticdiff($e[0]) + automaticdiff($e[1]);
	else if($e[2] == "-") return automaticdiff($e[0]) - automaticdiff($e[1]);
	else if($e[2] == "*") return automaticdiff($e[0]) * mathsolve($e[1]) + automaticdiff($e[1]) * mathsolve($e[0]);
	else if($e[2] == "/") return (automaticdiff($e[0]) * mathsolve($e[1]) - automaticdiff($e[1]) * mathsolve($e[0])) / pow(mathsolve($e[1]), 2);
	else if($e[2] == "^") return mathsolve($e[1]) * pow(mathsolve($e[0]), mathsolve($e[1] - 1)) * automaticdiff($e[0]) + pow(mathsolve($e[0]), mathsolve($e[1])) * log(mathsolve($e[0])) * automaticdiff($e[1]);
}

function symbolicdiff($string){

 	global $var_matrix;

	//Exclui todos os espaços
	$string = str_replace(' ', '', $string);

	if(ContarOperadorForadeParentesis($string, "+")){
		$e = explodeoperador($string, "+");
	}else if(ContarOperadorForadeParentesis($string, "-")){
		$e = explodeoperador($string, "-");
	}else if(ContarOperadorForadeParentesis($string, "*")){
		$e = explodeoperador($string, "*");
	}else if(ContarOperadorForadeParentesis($string, "/")){
		$e = explodeoperador($string, "/");
	}else if(ContarOperadorForadeParentesis($string, "^")){
		$e = explodeoperador($string, "^");
	// Checa todas as funções matemáticas, caso seja uma inexistente retorna uma exceção, caso nenhuma delas, retorna a própria string
	}else{
		return checkmathfunctionsinsymbolicdiff($string);
	}

	print_r($e);

	// Caso para números negativos
	if($e[0] == "") $e[0] = "0";

	if($e[2] == "+") return symbolicadder(symbolicdiff($e[0]), symbolicdiff($e[1]));
	else if($e[2] == "-") return symbolicsubtractor(symbolicdiff($e[0]), symbolicdiff($e[1]));
	else if($e[2] == "*") return symbolicadder(symbolicmultiplier(symbolicdiff($e[0]), $e[1]), symbolicmultiplier(symbolicdiff($e[1]), $e[0]));
	else if($e[2] == "/") return symbolicdivisor(symbolicsubtractor(symbolicmultiplier(symbolicdiff($e[0]), $e[1]), symbolicmultiplier(symbolicdiff($e[1]), $e[0])), symbolicpower($e[1], 2));
	else if($e[2] == "^") return symbolicadder(symbolicmultiplier(symbolicmultiplier($e[1], symbolicpower($e[0], symbolicsubtractor($e[1], 1))), symbolicdiff($e[0])), symbolicmultiplier(symbolicmultiplier(symbolicpower($e[0], $e[1]), "log(".$e[0].")"), symbolicdiff($e[1])));
}

$var_matrix = array();
$var_todiff = "x";
$var_matrix["x"] = M_PI/4;
$var_matrix["y"] = 2;

//parsingrecursivo("mechupa*teste*penis/cu-piru+caralho*piroca/buceta-porra+(cacete-piu)");
/*try {
    echo mathsolve("cos(1)^(sin(3^4))*4/5+2-3*5", $var_matrix);
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}*/

try {
    //echo symbolicdiff("(sin(3*x^2+(2*x/(x^3+2)))*(x^2+2)*(x^3+1))/((x^5+x^4+x^3)*(x^3+(x/(x^5+5*x^3))))");
    //$time = microtime();
    echo automaticdiff("(sin(3*x^2+(2*x/(x^3+2)))*(x^2+2)*(x^3+1))/((x^5+x^4+x^3)*(x^3+(x/(sin(x^3/(x^2+2*x))))))");
    //$time = microtime() - $time;
    //echo " TIME: $time";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

//echo "<br>";
//echo pow(cos(1), sin(pow(3,4)))*4/5+2-3*5;

?>